package com.ruoyi.biz.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.ruoyi.biz.domain.BizProject;
import com.ruoyi.biz.domain.BizProjectPlan;
import com.ruoyi.biz.model.req.ReceiptProjectReq;
import com.ruoyi.biz.model.resp.BizReceiptResp;
import com.ruoyi.biz.model.resp.ReceiptProjectResp;
import com.ruoyi.common.utils.DateUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.biz.mapper.BizReceiptMapper;
import com.ruoyi.biz.domain.BizReceipt;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import static com.ruoyi.common.utils.SecurityUtils.getUserId;


/**
 * 收款登记Service业务层处理
 *
 * @author tianl
 * @date 2025-01-01
 */
@Service
public class BizReceiptService extends ServiceImpl<BizReceiptMapper, BizReceipt> {
    @Autowired
    private ProjectQueryService projectQueryService;
    @Autowired
    private BizProjectPlanService bizProjectPlanService;
    @Autowired
    private BizProjectService bizProjectService;


    public BigDecimal surplus(Long projectId) {
        BizProject bizProject = bizProjectService.selectById(projectId);
        if (bizProject != null) {
            List<BizReceiptResp> list = baseMapper.listByProjectIds(Arrays.asList(projectId));
            BigDecimal total = list.stream().map(BizReceiptResp::getReceiptMoney).reduce(BigDecimal.ZERO, BigDecimal::add); // 计算总和
            BigDecimal surplus = bizProject.getTotalAmount().subtract(total);
            if (surplus.compareTo(BigDecimal.ZERO) <= 0) {
                return BigDecimal.ZERO;
            }
            return surplus;
        }
        return BigDecimal.ZERO;
    }

    /**
     * 分页查询收款登记
     */
    public IPage<ReceiptProjectResp> listPage(ReceiptProjectReq req) {
        IPage<ReceiptProjectResp> projectPage = projectQueryService.listReceipt(req);
        List<Long> projectIds = projectPage.getRecords().stream().map(ReceiptProjectResp::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(projectIds)) {
            return projectPage;
        }
        List<BizProjectPlan> plans = bizProjectPlanService.listByProjectIds(projectIds, 0);
        List<BizReceiptResp> receipts = baseMapper.listByProjectIds(projectIds);
        if (req.getReceiptTimeStart() != null && req.getReceiptTimeEnd() != null) {
            receipts = receipts.stream()
                    .filter(r -> r.getReceiptTime().compareTo(req.getReceiptTimeStart()) >= 0
                            && r.getReceiptTime().compareTo(req.getReceiptTimeEnd()) <= 0)
                    .collect(Collectors.toList());
        }
        Map<Long, List<BizProjectPlan>> projectPlanMap = plans.stream().collect(Collectors.groupingBy(BizProjectPlan::getProjectId));
        Map<Long, List<BizReceiptResp>> projectMap = receipts.stream().collect(Collectors.groupingBy(BizReceiptResp::getProjectId));
        for (ReceiptProjectResp resp : projectPage.getRecords()) {
            int planNum = 1;
            if (projectPlanMap.containsKey(resp.getProjectId())) {
                resp.setPlanList(projectPlanMap.get(resp.getProjectId()));
                planNum = resp.getPlanList().size();
            } else {
                BizProjectPlan tmp = new BizProjectPlan();
                tmp.setStage("默认收款");
                tmp.setTime("-");
                tmp.setMoney(resp.getTotalAmount());
                resp.setPlanList(Arrays.asList(tmp));
            }
            resp.setReceiptPlan(planNum);
            if (projectMap.containsKey(resp.getProjectId())) {
                List<BizReceiptResp> tmpList = projectMap.get(resp.getProjectId());
                resp.setReceiptList(tmpList);
                resp.setReceiptReal(tmpList.size());
            } else {
                resp.setReceiptList(new ArrayList<>());
                resp.setReceiptReal(0);
            }
        }
        return projectPage;
    }

    /**
     * 查询收款登记列表
     */
    public List<BizReceiptResp> list(ReceiptProjectReq req) {
        List<ReceiptProjectResp> projectPage = projectQueryService.listAllReceipt(req);
        List<Long> projectIds = projectPage.stream().map(ReceiptProjectResp::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(projectIds)) {
            return new ArrayList<>();
        }
        List<BizReceiptResp> receipts = baseMapper.listByProjectIds(projectIds);
        if (req.getReceiptTimeStart() != null && req.getReceiptTimeEnd() != null) {
            receipts = receipts.stream()
                    .filter(r -> r.getReceiptTime().compareTo(req.getReceiptTimeStart()) >= 0
                            && r.getReceiptTime().compareTo(req.getReceiptTimeEnd()) <= 0)
                    .collect(Collectors.toList());
        }
        return receipts;
    }

    /**
     * 根据ID查询
     */
    public BizReceiptResp selectById(Long id) {
        return baseMapper.selectDetail(id);
    }

    /**
     * 新增修改收款登记
     */
    @Transactional(rollbackFor = Exception.class)
    public void beforeSave(BizReceipt bizReceipt) {
        if (bizReceipt.getId() != null) {
            bizReceipt.setUpdateTime(DateUtils.getNowDate());
        } else {
            bizReceipt.setCreateTime(DateUtils.getNowDate());
            bizReceipt.setUpdateTime(DateUtils.getNowDate());
            bizReceipt.setUserId(getUserId());
        }
        saveOrUpdate(bizReceipt);
        //计算收款
        bizProjectService.calcProjectReceipt(bizReceipt.getProjectId());
    }

    /**
     * 批量删除收款登记
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(Long[] ids) {
        List<Long> projectIds = new ArrayList<>();
        for (Long id : ids) {
            BizReceipt bizReceipt = selectById(id);
            if (bizReceipt != null) {
                projectIds.add(bizReceipt.getProjectId());
            }
        }
        baseMapper.deleteBatchIds(Arrays.asList(ids));
        for (Long projectId : projectIds) {
            //计算收款
            bizProjectService.calcProjectReceipt(projectId);
        }
    }

}
